
package com.example.testutil.util.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

import com.example.testutil.R;

public class RoundImageView extends ImageView {

    private static final int TYPE_CIRCLE = 0;

    private static final int TYPE_ROUND = 1;

    private static final int DEFAULT_RADIUS = 10;

    private Paint mPaint;

    private Matrix matrix;

    private BitmapShader mShader;

    private int mRadius;

    private int roundradius;

    private int type;

    private int mWidth;

    private RectF mroundrectF;

    public RoundImageView(Context context) {
        this(context, null);
    }

    public RoundImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray mArray = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView);
        roundradius = mArray.getInt(R.styleable.RoundImageView_borderRadius, DEFAULT_RADIUS);
        type = mArray.getInt(R.styleable.RoundImageView_type, TYPE_CIRCLE);
        mArray.recycle();
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        matrix = new Matrix();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (type == TYPE_CIRCLE) {
            mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());
            mRadius = mWidth / 2;
            setMeasuredDimension(mWidth, mWidth);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (getDrawable() == null) {
            return;
        }
        setBitmapShader();
        if (type == TYPE_ROUND) {
            canvas.drawRoundRect(mroundrectF, roundradius, roundradius, mPaint);
        } else {
            canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
        }

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (type == TYPE_ROUND) {
            mroundrectF = new RectF(0, 0, getWidth(), getHeight());
        }
    }

    private void setBitmapShader() {
        Drawable mDrawable = getDrawable();
        if (mDrawable == null) {
            return;
        }
        Bitmap mBitmap = drawDawabletoBitmap(mDrawable);
        mShader = new BitmapShader(mBitmap, TileMode.CLAMP, TileMode.CLAMP);
        float scale = 1.0f;
        if (type == TYPE_CIRCLE) {
            int basesize = Math.max(mBitmap.getWidth(), mBitmap.getHeight());
            scale = mWidth * 1.0f / basesize;
        } else if (type == TYPE_ROUND) {
            scale = Math.max(getWidth() * 1.0f / mBitmap.getWidth(), getHeight() * 1.0f / mBitmap.getHeight());
        }
        matrix.setScale(scale, scale);
        mShader.setLocalMatrix(matrix);
        mPaint.setShader(mShader);
    }

    private Bitmap drawDawabletoBitmap(Drawable mDrawable) {
        if (mDrawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) mDrawable).getBitmap();
        }
        int w = mDrawable.getIntrinsicWidth();
        int h = mDrawable.getIntrinsicHeight();
        Bitmap mBitmap = Bitmap.createBitmap(w, h, Config.ARGB_8888);
        Canvas mCanvas = new Canvas(mBitmap);
        mDrawable.setBounds(0, 0, w, h);
        mDrawable.draw(mCanvas);
        return mBitmap;
    }
}
